home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga Plus Special 23
/
AMIGAplus Sonderheft 23 (2000)(Falke)(DE)[!].iso
/
Updates
/
Librarys
/
MMULib
/
Autodocs
/
exceptions.doc
< prev
next >
Wrap
Text File
|
1999-05-26
|
36KB
|
808 lines
E X C E P T I O N - H A N D L E R D E T A I L S
------------------------------------------------------------------------------
Abstract:
This document defines the exception handler mechanism of the mmu.library
and how to make use of it.
Please study it carefully before you try to implement an mmu.lib
exception handler.
For details about the concepts of a "context", read the mmu.doc.
------------------------------------------------------------------------------
What is a bus error exception:
A bus error can be understood as a sort-of "interrupt" which is triggered
by either a software fault or a hardware signal related to acessing memory
or external devices in an unsupported fashion, like accessing a non-available
memory location or writing to a write-protected memory region.
All bus errors are re-directed to the MMU.library, but some of them remain
unhandled and are passed over to the exec.library. Some of the remaining
errors are handled automatically by the library, and those that remain
will cause your "context hooks" to be called, as installed by the
"AddContextHook" and "AddMessageHook" vectors of the mmu.library.
The members of the MC680x0 family generate so called "bus error" for the
following situations:
- True physical bus errors:
The CPU tried to access an external device, but this request was aborted
by pulling the "bus error input" control line (TEA) of the CPU low.
These bus errors are generated by an external bus control logic, avail-
able for some Amiga models, on access of non-available memory.
- Access errors:
These errors are generated by the MMU for a non-valid access of
a memory "page". As far as the MMU is concerned, complete memory is
split into adjacent pages of a fixed size, usually of size 1K or 4K,
and the MMU holds access rules, the so called "properties" for each
of these pages. If these rules are violated, an access error is
generated. The following violations may arise:
The CPU tried to access a page of memory marked by the MMU as
"non-resident", or tried to write to a memory block which is write-
protected, or tried to access a memory block in user mode which is
marked as "supervisor only" access.
Of all of these bus errors, the mmu.library handles only the part which it
is "interested in". True physical bus errors are not handled by the
MMU.library and passed thru to the exec exception handler - which again, calls
the exception handler of the task that caused the exception. Additionally,
the MMU.library does not try to fix bus errors caused by so called "locked
transfers", i.e. the instructions "TAS","CAS" and "CAS2". These instructions
are only useful for multi-processor machines and not supported by the Amiga
hardware architecture anyways. A legal Amiga program *must not* use them.
Furthermore, the "MOVE16" instruction accesses of the 040 and 060 processors
are not handled, too, for the same reason. All these errors are passed thru
to exec, and remain unhandled. They will usually force a fatal software
failure.
An additional special case - which might be interesting for the experts -
is writing to memory by "instruction function code". This is only possibly
by loading this function code to the "dfc" register and then using the
privileged "moves" instruction to write instruction data. This is unsupported,
too. Just write instructions with "move", then flush the cache. This is, too,
what the dos.library does when loading code.
All remaining accesses are handled by the MMU library, and are first filtered
again. The MMU library distinguishes:
- User mode and supervisor mode accesses.
All exec tasks MUST run in user mode, and this is the "default" situation.
The user mode exceptions are handled according to the "MMU context" they
are generated by, or, equivalently, the context the current task is attached
to. All supervisor mode accesses are managed by one single context, the
"supervisor context".
- Data vs. instruction accesses.
Whether the bus error happened due to faulted access of data, or whether
the CPU tried to fetch instructions, and this instruction fetch faulted.
Instruction write accesses, as they might have been generated by a "moves",
might or might not be handled, this is implementation specific. The CPU
itself never generates these accesses when fetching code, the only
possibility is a "moves" instruction.
- Read vs. write accesses.
Whether data was about to be read by the CPU, or the CPU tried to write
out data. Instruction accesses by the CPU are always of reads.
Accesses to the stack, as for subroutine calls or "link" instructions
are regarded as data accesses, too. (Read about special caveats about
the stack, below!)
Amongst all these types, the MMU library handles certain special cases
automatically. You never see these faults from your context hooks, they
are completely transparent and handled by the library as a special service.
- AbsExecBase reads.
To be able to mark the first memory page as "invalid", the MMU library
filters out accesses to AbsExecBase itself in the first stage of the exception
handler, to emulate them as fast as possible. The library will try to emulate
the most popular instructions in software, for optimal performance. However,
still try to avoid reading AbsExecBase in your code. Make a copy to a static
library base on startup, and then use this backup copy whenever possible.
Most modern C compilers do that automatically anyways, but assembly language
authors should keep this in mind.
DON'T (slow!) DO (fast)
move.l AbsExecBase,a6 move.l mn_SysBase(a4),a6
In case the special threatment of AbsExecBase is not desired, set the
MCXTAG_EXECBASE tag value of the CreateMMUContext() call to FALSE. This might
be interesting for emulators, for example.
Remember that interrupt code is handled by the supervisor context, AND NOT
BY YOUR USER CONTEXT. Hence, accessing AbsExecBase from within interrupts is
always valid, simply because the supervisor context is always build by the
library itself, and this flag is always set on creation of this context.
DO NOT touch the supervisor context unless you know precisely what you're
doing.
- Accesses above 0x0400 in the first memory page.
The mmu.library emulates accesses above addresses 0x0400 to the first
page in memory. This is again to allow setting the first page to "invalid"
for tracing access errors in the autovector region. Accesses to addresses
above and including 0x400 in the first page are therefore always legal.
This feature can be disabled again with the MCXTAG_EXECBASE flag, see above.
AVOID THESE ACCESSES, THEY ARE EMULATED IN SOFTWARE AND VERY SLOW.
Starting with Os 3.0, exec tries to help these MMU programs by starting
chip memory at 0x1000, not at 0x0400 as usual, if a 040 or 060 CPU is
available. This means that for page sizes of 4K for the 040 and 060, and
for page sizes of 1K for the 030 and 68851/020 MMU, no accesses need to
be emulated. Please keep this in mind when using the MMU because THE
EMULATION CODE IS SLOW. Try to use these "natural" page sizes whenever
possible.
If not possible, try to relolate the libraries and buffers in this memory
region, usually some graphics.library buffers, the expansion library base,
and - possibly - the exec library.
Trying to execute code in this memory region does work, but is really, really
slow. Each instruction access has to go thru the mmu.library exception
handler, so feel prepared that your computer runs in "slo-mo mode" if you
don't follow these rules.
- Writes to MAPP_ROM pages.
The mmu.library tries to cancel writes to pages marked as "ROM". Writes
to these pages will generate an access error, which is "ignored" by
the mmu.library. Hence, memory regions marked as "ROM" will get an
effective "silent" write protection. However, keep in mind that a write
to "ROM" area is still slow because it includes running the exception handler.
This goes even more for the 060 CPU because it includes copying the "ROM"
to a dummy writable backup page into which the write is then redirected.
Special care must be taken for "misaligned" writes, i.e. writes that hit
the "border" of a ROM region and go par